/*
 * @Description: 
 * @FilePath: /STM32F103/USER/bsp/gpio.h
 * @Author: Wei Zhou
 * @Github: https://github.com/zromyk
 * @Date: 2021-05-12 20:17:46
 * @LastEditors: Wei Zhou
 * @LastEditTime: 2021-05-12 23:09:34
 * @Copyright: Copyright ? 2017 muyiro. All rights reserved.
 */

#ifndef GPIO_INIT_H
#define GPIO_INIT_H

#include "my_include.h"

#define BITBAND(addr, bitnum)       ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) 
#define MEM_ADDR(addr)              (*((volatile unsigned long  *)(addr)))
#define BIT_ADDR(addr, bitnum)      MEM_ADDR(BITBAND(addr, bitnum)) 

#define GPIOA_ODR_Addr    (GPIOA_BASE + 12) /* 0x4001080C */
#define GPIOB_ODR_Addr    (GPIOB_BASE + 12) /* 0x40010C0C */
#define GPIOC_ODR_Addr    (GPIOC_BASE + 12) /* 0x4001100C */
#define GPIOD_ODR_Addr    (GPIOD_BASE + 12) /* 0x4001140C */
#define GPIOE_ODR_Addr    (GPIOE_BASE + 12) /* 0x4001180C */
#define GPIOF_ODR_Addr    (GPIOF_BASE + 12) /* 0x40011A0C */
#define GPIOG_ODR_Addr    (GPIOG_BASE + 12) /* 0x40011E0C */

#define GPIOA_IDR_Addr    (GPIOA_BASE + 8) /* 0x40010808 */
#define GPIOB_IDR_Addr    (GPIOB_BASE + 8) /* 0x40010C08 */
#define GPIOC_IDR_Addr    (GPIOC_BASE + 8) /* 0x40011008 */
#define GPIOD_IDR_Addr    (GPIOD_BASE + 8) /* 0x40011408 */
#define GPIOE_IDR_Addr    (GPIOE_BASE + 8) /* 0x40011808 */
#define GPIOF_IDR_Addr    (GPIOF_BASE + 8) /* 0x40011A08 */
#define GPIOG_IDR_Addr    (GPIOG_BASE + 8) /* 0x40011E08 */

#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr, n) 
#define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr, n) 

#define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr, n) 
#define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr, n) 

#define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr, n) 
#define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr, n) 

#define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr, n) 
#define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr, n) 

#define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr, n) 
#define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr, n) 

#define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr, n) 
#define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr, n) 

#define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr, n) 
#define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr, n) 

#define getGPIO(pin)    ((pin & 0xF0) >> 4)
#define getPIN(pin)     (pin & 0x0F)

typedef enum 
{
    PA0 = 0x00, PA1, PA2, PA3, PA4, PA5, PA6, PA7, PA8, PA9, PA10, PA11, PA12, PA13, PA14, PA15,
    PB0 = 0x10, PB1, PB2, PB3, PB4, PB5, PB6, PB7, PB8, PB9, PB10, PB11, PB12, PB13, PB14, PB15,
    PC0 = 0x20, PC1, PC2, PC3, PC4, PC5, PC6, PC7, PC8, PC9, PC10, PC11, PC12, PC13, PC14, PC15,
    PD0 = 0x30, PD1, PD2, PD3, PD4, PD5, PD6, PD7, PD8, PD9, PD10, PD11, PD12, PD13, PD14, PD15,
    PE0 = 0x40, PE1, PE2, PE3, PE4, PE5, PE6, PE7, PE8, PE9, PE10, PE11, PE12, PE13, PE14, PE15,
    PF0 = 0x50, PF1, PF2, PF3, PF4, PF5, PF6, PF7, PF8, PF9, PF10, PF11, PF12, PF13, PF14, PF15,
    PG0 = 0x60, PG1, PG2, PG3, PG4, PG5, PG6, PG7, PG8, PG9, PG10, PG11, PG12, PG13, PG14, PG15
} PIN_Dev;

typedef enum
{ 
    GPIO_PuPd_NOPULL = 0x00,
    GPIO_PuPd_UP     = 0x01,
    GPIO_PuPd_DOWN   = 0x02
} GPIOPuPd_TypeDef;

/* initialize functions ----------------------------------------------------- */

/**
 * @brief  GPIO 初始化（输出）
 * @param  pin: Select from PIN_Dev.
 * @param  bit: low or high level. (0 or 1)
 * @retval None
 */
void gpio_out_init(PIN_Dev pin, uint16_t bit);

/**
 * @brief  GPIO 初始化（输入）
 * @param  pin: Select from PIN_Dev.
 * @param  PuPd: no pull, pull up or pull down.
 *             GPIO_PuPd_NOPULL = 0x00,
 *             GPIO_PuPd_UP     = 0x01,
 *             GPIO_PuPd_DOWN   = 0x02
 * @retval None
 */
void gpio_in_init(PIN_Dev pin, GPIOPuPd_TypeDef PuPd);

/**
 * @brief  GPIO 初始化（复用）
 * @param  pin: Select from PIN_Dev.
 * @retval None
 */
void gpio_af_init(PIN_Dev pin);

/**
 * @brief  GPIO 写
 * @param  pin: Select from PIN_Dev.
 * @param  bit: low or high level. (0 or 1)
 * @retval None
 */
void gpio_write(PIN_Dev pin, uint16_t bit);

/**
 * @brief  GPIO 读
 * @param  pin: Select from PIN_Dev.
 * @retval None
 */
uint8_t gpio_read(PIN_Dev pin);

#endif /* GPIO_INIT_H */
